﻿using System;
using System.Linq;
using System.Reflection;
using System.Collections.Generic;
using MWTools.Client.Common;
using WikiTools;
using Redemption;
using Microsoft.Office.Interop.Outlook;
using WikiTools.Access;
using MWTools.Client.Common.Interfaces;
using MWTools.Client.Helpers;

namespace MWTools.Client
{
    public class OutlookController : ControllerBase, IDisposable
    {
        private _Application _outlookApplication = new Application();

        public string WikiUserName { get; set; }
        public string WikiPassword { get; set; }
        public string WikiUri { get; set; }

        /// <summary>
        /// Initializes a new instance of the OutlookController class.
        /// </summary>
        public OutlookController(string wikiUserName, string wikiPassword, string wikiUri)
        {
            WikiUserName = wikiUserName;
            WikiPassword = wikiPassword;
            WikiUri = wikiUri;
        }

        public OutlookController()
        {
        }

        public RDOSession MapiSession
        {
            get
            {
                Logger.DebugFormat("GetMapiSession", "");
                RDOSession session = new RDOSession();

                try
                {
                    PropertyInfo pi = _outlookApplication.Session.GetType().GetProperty("MAPIOBJECT");
                    session.MAPIOBJECT = pi.GetValue(_outlookApplication.Session, null);
                }
                catch (System.Exception ex)
                {
                    Logger.Fatal("GetMapiSession", ex);
                    throw;
                }

                return session;
            }
        }

        private string extractPropertiesFromOutlookItem(object item)
        {
            PropertyInfo[] properties = null;
            string typeName = "outlookItem";
            string result = String.Empty;

            if (item is IRDOAppointmentItem)
            {
                properties = typeof(_AppointmentItem).GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty);
            }
            else if (item is IRDOContactItem)
            {
            	properties = typeof(_ContactItem).GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty);
            }
            else if (item is IRDOTaskItem)
            {
                properties = typeof(_TaskItem).GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty);
            }
            else
            {
                properties = typeof(_MailItem).GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.GetProperty);
            }

            using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
            {
                using (System.Xml.XmlTextWriter writer = new System.Xml.XmlTextWriter(ms, System.Text.UTF8Encoding.UTF8))
                {
                    writer.WriteStartDocument();
                    writer.WriteStartElement(typeName);

                    foreach (var pi in properties)
                    {
                        object value = null;

                        try
                        {
                            value = item.GetType().InvokeMember(
                                        pi.Name,
                                        BindingFlags.Instance | BindingFlags.GetField | BindingFlags.GetProperty | BindingFlags.NonPublic,
                                        null,
                                        item,
                                        null);

                            if(pi.Name == "HTMLBody")
                            {
                                value = new PandocWrapper.PandocWrapper().Convert((string)value, "html", "mediawiki");
                            }

                            if (value.GetType().IsCOMObject)
                                continue;

                            writer.WriteStartElement(pi.Name);
                            writer.WriteString(value.ToString());
                            writer.WriteEndElement();
                        }
                        catch (System.Exception ex)
                        {
                            Logger.DebugFormat("OutlookController.extractProperties", "error parsing {0}", pi.Name);
                        }
                    }
                    writer.WriteEndElement();
                    writer.Flush();
                    writer.BaseStream.Seek(0, System.IO.SeekOrigin.Begin);

                    using (System.IO.StreamReader sr = new System.IO.StreamReader(writer.BaseStream))
                    {
                        result = sr.ReadToEnd();

                    }
                }
            }

            return result;
        }

        private void shellPage()
        {
            
        }

        public override void SubmitItem(object item)
        {
            if (string.IsNullOrEmpty(AppContext.Current.UserSetting.MWToolsServerUri))
                System.Windows.Forms.MessageBox.Show("Your Mediawiki server uri is invalid, please fix in options");


            Logger.DebugFormat("OutlookController.SubmitItemToWIki", "getting entryId...");
            string entryId = item.GetType().InvokeMember(
                                   "EntryID",
                                   BindingFlags.Instance | BindingFlags.GetField | BindingFlags.GetProperty | BindingFlags.NonPublic,
                                   null,
                                   item,
                                   null) as string;

            int? itemClass = item.GetType().InvokeMember(
                       "Class",
                       BindingFlags.Instance | BindingFlags.GetField | BindingFlags.GetProperty | BindingFlags.NonPublic,
                       null,
                       item,
                       null) as int?;

           // RDOFolder rdoFolder = MapiSession.GetFolderFromID(folder.EntryID, Type.Missing, Type.Missing);
            
            if (item is _AppointmentItem)
            {
                item = (IRDOAppointmentItem)MapiSession.GetMessageFromID(entryId, Type.Missing, Type.Missing);
                //(entryId, Type.Missing, Type.Missing)
            }
            else if (item is _ContactItem)
            {
                item = (IRDOContactItem)MapiSession.GetMessageFromID(entryId, Type.Missing, Type.Missing);
                //(entryId, Type.Missing, Type.Missing)
            }
            else if (item is _TaskItem)
            {
                item = (IRDOTaskItem)MapiSession.GetMessageFromID(entryId, Type.Missing, Type.Missing); ;
            }
            else
            {
                item = MapiSession.GetMessageFromID(entryId, Type.Missing, Type.Missing);
            }

            Logger.DebugFormat("OutlookController.SubmitItemToWIki", "unpacking {0}...", entryId);
            string xmlResult = extractPropertiesFromOutlookItem(item);

            PluginHelpers.SubmitItemToPlugin(entryId, xmlResult);
            //   }

        }

        public void Dispose()
        {
        }
    }
}
